#pragma once

#include <map>
#include <unordered_map>
#include <string>
#include <vector>
using namespace std;


#define MAX_NUM 1000
class JsonObject;
class JsonArray;
struct ptrCmp
{
    bool operator()( const char * s1, const char * s2 ) const
    {
        return strcmp( s1, s2 ) < 0;
    }
};
/*
Json 语法

    object = {} | { members }
    members = pair | pair , members
    pair = string : value
    array = [] | [ elements ]
    elements = value  | value , elements
    value = string | number | object | array | true | false | null
*/

enum ValueType
{
    STRING,
    I_NUMBER,
    F_NUMBER,
    OBJECT,
    ARRAY ,
    Value_Bool,
    _NULL
};
/*
    Value 用来记录 Josn Object里面的元素
    Value 是一个 union 联合体
        并且有一个 type 来记录 其 具体类型
*/
struct Value
{
    ValueType type;
    // union 
    // {
        char *  String;
        int i_number;
        float f_number;
        JsonObject * Json_Object; 
        JsonArray * Json_Array;
        bool bool_value;
    // };
    
};

/*
    JsonObject 是一个 键值对 集合
    map<string,Value>

    对应的语法
        object = {} | { members }
        members = pair | pair , members
        pair = string : value
*/

class JsonObject
{
public:
    pair<char* ,Value*>map_object [MAX_NUM];
    int num = 0;
public:
    void put( char* key,   Value * pvalue)
    {
        //map_object.push_back(pair<char*, Value*>(key, pvalue));
        //map_object.emplace(key,pvalue);
        map_object[num] = pair<char*, Value*>(key, pvalue);
        num++;
    }
    // vector<pair<char* ,Value*>> & getMap()
    // {
    //     return map_object;
    // }
    // pair<char* ,Value*>* getMap()
    // {
    //     return map_object;
    // }
    
};

/*
    JsonArray 是一个 Value 集合
    vector<Value>

    对应的语法
        array = [] | [ elements ]
        elements = value  | value , elements
        value = string | number | object | array | true | false | null
*/

class JsonArray
{
public:
    //vector<Value*> array_value;
    Value* array_value[MAX_NUM];
    int num  =0;
public :
    void put( Value * pvalue)
    {
        array_value[num] = pvalue;
        num++;
    }
    // vector<Value*> & getValueArray()
    // {
    //     return array_value;
    // }
};


//////////////////
//打印函数
void printIdent(int identLevel);
void printValue(Value& va,int identLevel);
void printJsonObject(JsonObject & obj,int identLevel);
void printJsonArray(JsonArray & arr,int identLevel);

void printIdent(int identLevel)
{
    for(int i=0;i<identLevel;i++)
    {
        cout<<"  ";
    }
}

void printValue(Value& va,int identLevel)
{
    switch (va.type)
    {
        case STRING:
        {
            printf("%s",va.String);
            break;
        }
        case I_NUMBER:
        {
            std::cout<<va.i_number;
            break;
        }
        case F_NUMBER:
        {
            std::cout<<va.f_number;
            break;
        }
        case OBJECT:
        {
            printIdent(identLevel);printJsonObject(*va.Json_Object,identLevel);
            break;
        }
        case ARRAY :
        {
            printIdent(identLevel);printJsonArray(*va.Json_Array,identLevel);
            break;
        }
        case Value_Bool:
        {
            std::cout<<va.bool_value;
            break;
        }
    }

}
void printJsonObject(JsonObject & obj,int identLevel)
{
    printIdent(identLevel);printf("{\n");
    // vector<pair<char* ,Value*>>::iterator iter;
    // vector<pair<char* ,Value*>>& maps = obj.getMap();
    // for(iter = maps.begin();iter != maps.end();iter++)

    // {
    //     printIdent(identLevel+1);
    //     printf("%s : ",iter->first);
    //     printValue(*(iter->second),identLevel +1);
    //     std::cout<<","<<endl;
    // }
    //obj.map_object[0];
    for(int i = 0;i<obj.num;i++)
    {
        printIdent(identLevel+1);
        printf("%s : ",obj.map_object[i].first);
        printValue(*((obj.map_object[i]).second),identLevel +1);
        std::cout<<","<<endl;
    }


    std::cout<<endl;
    printIdent(identLevel); printf("}\n");
}

void printJsonArray(JsonArray & arr,int identLevel)
{
    printIdent(identLevel);printf("[\n");
    
    //vector<Value*> & arrays = arr.getValueArray();
    int len = arr.num;
    for(int i=0;i<len;i++)
    {
        printValue(*arr.array_value[i],identLevel + 1);
        std::cout<<","<<endl;
    }
    std::cout<<endl;
    printIdent(identLevel); printf("]\n");

}

